using System.Text.Json;
using McpApi.Models;

namespace McpApi.Services
{
    /// <summary>
    /// MCP协议处理器
    /// </summary>
    public class MCPProtocolHandler
    {
        private readonly ILogger<MCPProtocolHandler> _logger;
        private readonly IToolRegistry _toolRegistry;
        private readonly JsonSerializerOptions _jsonOptions;

        // 服务器状态
        private bool _isInitialized = false;
        private ClientInfo? _clientInfo;

        public MCPProtocolHandler(ILogger<MCPProtocolHandler> logger, IToolRegistry toolRegistry)
        {
            _logger = logger;
            _toolRegistry = toolRegistry;
            _jsonOptions = new JsonSerializerOptions
            {
                PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
                WriteIndented = true
            };
        }

        /// <summary>
        /// 处理JSON-RPC请求
        /// </summary>
        public async Task<string> HandleRequestAsync(string requestJson)
        {
            try
            {
                _logger.LogDebug("收到MCP请求: {Request}", requestJson);

                var request = JsonSerializer.Deserialize<JsonRpcRequest>(requestJson, _jsonOptions);
                if (request == null)
                {
                    return CreateErrorResponse(null, -32700, "Parse error");
                }

                JsonRpcResponse response = request.Method switch
                {
                    "initialize" => await HandleInitializeAsync(request),
                    "initialized" => await HandleInitializedAsync(request),
                    "tools/list" => await HandleListToolsAsync(request),
                    "tools/call" => await HandleCallToolAsync(request),
                    "ping" => HandlePing(request),
                    _ => CreateErrorResponseObject(request.Id, -32601, $"Method not found: {request.Method}")
                };

                var responseJson = JsonSerializer.Serialize(response, _jsonOptions);
                _logger.LogDebug("发送MCP响应: {Response}", responseJson);

                return responseJson;
            }
            catch (JsonException ex)
            {
                _logger.LogError(ex, "JSON解析错误");
                return CreateErrorResponse(null, -32700, "Parse error");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "处理MCP请求时发生错误");
                return CreateErrorResponse(null, -32603, "Internal error");
            }
        }

        /// <summary>
        /// 处理初始化请求
        /// </summary>
        private Task<JsonRpcResponse> HandleInitializeAsync(JsonRpcRequest request)
        {
            try
            {
                var initRequest = JsonSerializer.Deserialize<InitializeRequest>(
                    JsonSerializer.Serialize(request.Params), _jsonOptions);

                if (initRequest == null)
                {
                    return Task.FromResult(CreateErrorResponseObject(request.Id, -32602, "Invalid params"));
                }

                _clientInfo = initRequest.ClientInfo;
                _logger.LogInformation("客户端连接: {ClientName} v{ClientVersion}",
                    _clientInfo.Name, _clientInfo.Version);

                var response = new InitializeResponse
                {
                    ProtocolVersion = "2024-11-05",
                    ServerInfo = new ServerInfo
                    {
                        Name = "MES MCP Server",
                        Version = "1.0.0"
                    },
                    Capabilities = new ServerCapabilities
                    {
                        Tools = new ToolsCapability
                        {
                            ListChanged = false
                        }
                    }
                };

                return Task.FromResult(new JsonRpcResponse
                {
                    Id = request.Id,
                    Result = response
                });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "处理初始化请求失败");
                return Task.FromResult(CreateErrorResponseObject(request.Id, -32603, "Initialize failed"));
            }
        }

        /// <summary>
        /// 处理初始化完成通知
        /// </summary>
        private async Task<JsonRpcResponse> HandleInitializedAsync(JsonRpcRequest request)
        {
            await Task.CompletedTask; // 保持异步方法签名
            _isInitialized = true;
            _logger.LogInformation("MCP连接初始化完成");

            return new JsonRpcResponse
            {
                Id = request.Id,
                Result = new { status = "initialized" }
            };
        }

        /// <summary>
        /// 处理工具列表请求
        /// </summary>
        private async Task<JsonRpcResponse> HandleListToolsAsync(JsonRpcRequest request)
        {
            try
            {
                if (!_isInitialized)
                {
                    return CreateErrorResponseObject(request.Id, -32002, "Server not initialized");
                }

                var tools = await _toolRegistry.GetToolsAsync();

                var response = new ListToolsResponse
                {
                    Tools = tools.ToList()
                };

                _logger.LogInformation("返回 {Count} 个可用工具", tools.Count());

                return new JsonRpcResponse
                {
                    Id = request.Id,
                    Result = response
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取工具列表失败");
                return CreateErrorResponseObject(request.Id, -32603, "Failed to list tools");
            }
        }

        /// <summary>
        /// 处理工具调用请求
        /// </summary>
        private async Task<JsonRpcResponse> HandleCallToolAsync(JsonRpcRequest request)
        {
            try
            {
                if (!_isInitialized)
                {
                    return CreateErrorResponseObject(request.Id, -32002, "Server not initialized");
                }

                var callRequest = JsonSerializer.Deserialize<CallToolRequest>(
                    JsonSerializer.Serialize(request.Params), _jsonOptions);

                if (callRequest == null)
                {
                    return CreateErrorResponseObject(request.Id, -32602, "Invalid params");
                }

                _logger.LogInformation("调用工具: {ToolName}, 参数: {Arguments}",
                    callRequest.Name, JsonSerializer.Serialize(callRequest.Arguments));

                var result = await _toolRegistry.CallToolAsync(callRequest.Name, callRequest.Arguments);

                var response = new CallToolResponse
                {
                    Content = new List<ToolContent>
                    {
                        new ToolContent
                        {
                            Type = "text",
                            Text = result.Success ?
                                JsonSerializer.Serialize(result.Data, _jsonOptions) :
                                result.Message
                        }
                    },
                    IsError = !result.Success
                };

                return new JsonRpcResponse
                {
                    Id = request.Id,
                    Result = response
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "工具调用失败");
                return CreateErrorResponseObject(request.Id, -32603, "Tool call failed");
            }
        }

        /// <summary>
        /// 处理ping请求
        /// </summary>
        private JsonRpcResponse HandlePing(JsonRpcRequest request)
        {
            return new JsonRpcResponse
            {
                Id = request.Id,
                Result = new { status = "pong", timestamp = DateTime.UtcNow }
            };
        }

        /// <summary>
        /// 创建错误响应字符串
        /// </summary>
        private string CreateErrorResponse(object? id, int code, string message)
        {
            var errorResponse = new JsonRpcResponse
            {
                Id = id,
                Error = new JsonRpcError
                {
                    Code = code,
                    Message = message
                }
            };

            return JsonSerializer.Serialize(errorResponse, _jsonOptions);
        }

        /// <summary>
        /// 创建错误响应对象
        /// </summary>
        private JsonRpcResponse CreateErrorResponseObject(object? id, int code, string message)
        {
            return new JsonRpcResponse
            {
                Id = id,
                Error = new JsonRpcError
                {
                    Code = code,
                    Message = message
                }
            };
        }
    }
}
